package com.xyf.sys.service.impl;

import com.xyf.sys.config.CustomException;
import com.xyf.sys.domain.*;
import com.xyf.sys.mapper.GoodsCartItemMapper;
import com.xyf.sys.mapper.GoodsCartMapper;
import com.xyf.sys.service.IGoodsCartService;
import com.xyf.sys.service.IGoodsService;
import com.xyf.sys.service.IOrderService;
import com.xyf.sys.service.IUserService;
import com.xyf.sys.vo.GoodsCartPreOrderParam;
import com.xyf.sys.vo.PreOrderResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author R-H
 * @Date 2024/8/311157
 * @Description
 */
@Slf4j
@Service
public class GoodsCartServiceImpl implements IGoodsCartService {

    @Autowired
    private GoodsCartMapper cartMapper;
    @Autowired
    private GoodsCartItemMapper cartItemMapper;
    @Autowired
    private IUserService userService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IOrderService orderService;

    @Override
    public GoodsCart add(GoodsCartItem body) {
        User user = userService.get(body.getUserId());
        GoodsCartItem item = null;
        if (body.getId() != null) {
            item = this.cartItemMapper.selectByPrimaryKey(body.getId());
            item.setQuantity(item.getQuantity() + body.getQuantity());
        } else {
            item = body;
        }
        GoodsCart userCart = this.getUserCart(body.getUserId());
        Goods goods = goodsService.get(body.getGoodsId());
        if (goods.getLimitQuantity() != null && item.getQuantity() > goods.getLimitQuantity()){
            throw new CustomException("仅限量" + goods.getLimitQuantity());
        }
        BigDecimal price = goods.getPrice();
        item.setGoodsCartId(userCart.getId());
        item.setPricePerUnit(goods.getPrice());
        BigDecimal total = price.multiply(new BigDecimal(item.getQuantity())).setScale(2, RoundingMode.HALF_UP);
        item.setTotalPrice(total);
        item.setImg(goods.getAttachUrl());
        item.setStatus("0");
        item.setDelFlag("0");
        if (item.getQuantity() == 0){
            item.setDelFlag("1");
        }
        if (item.getId() == null) {
            item.setCreateBy(body.getUserId());
            item.setCreateTime(new Date());
            item.setTimestamp(new Date());
            item.setLastUpdateTime(new Date());
            item.setUserId(body.getUserId());
            cartItemMapper.insert(item);
        } else {
            item.setUserId(body.getUserId());
            item.setGoodsCartId(userCart.getId());
            item.setUpdateBy(body.getUserId());
            item.setUpdateTime(new Date());
            item.setLastUpdateTime(new Date());
            cartItemMapper.updateByPrimaryKey(item);
        }
        List<GoodsCartItem> cartItemList = cartItemMapper.selectByGoodsCartIdAndStatus(userCart.getId(), "0");
        BigDecimal sum = BigDecimal.ZERO;
        Integer num = 0;
        for (GoodsCartItem cartItem : cartItemList) {
            sum = sum.add(cartItem.getTotalPrice());
            num = num + cartItem.getQuantity();
        }
        userCart.setTotalPrice(sum);
        userCart.setNum(num);
        userCart.setUpdateTime(new Date());
        userCart.setLastUpdateTime(new Date());
        cartMapper.updateByPrimaryKey(userCart);
        userCart.setItemList(cartItemList);
        return userCart;
    }

    @Override
    public synchronized GoodsCart getUserCart(String userId) {
        GoodsCart cart = cartMapper.selectByUserIdAndStatus(userId, "0");
        if (cart == null) {
            cart = new GoodsCart();
            cart.setUserId(userId);
            cart.setStatus("0");
            cart.setNum(0);
            cart.setDelFlag("0");
            cart.setTotalPrice(BigDecimal.ZERO);
            cart.setCreateBy(userId);
            cart.setCreateTime(new Date());
            cart.setLastUpdateTime(new Date());
            cartMapper.insert(cart);
        }
        List<GoodsCartItem> list = cartItemMapper.selectByGoodsCartIdAndStatus(cart.getId(), "0");
        cart.setItemList(list);
        return cart;
    }

    @Override
    public GoodsCart clearCart(String userId) {
        GoodsCart cart = cartMapper.selectByUserIdAndStatus(userId, "0");
        if (cart != null) {
            cart.setStatus("2");
            cart.setUpdateBy(userId);
            cart.setUpdateTime(new Date());
            cart.setLastUpdateTime(new Date());
            cartMapper.updateByPrimaryKey(cart);
        }
        return getUserCart(userId);
    }

    @Override
    public void removeItem(Long itemId, String userId) {
        GoodsCartItem cartItem = cartItemMapper.selectByPrimaryKey(itemId);
        if (cartItem == null) {
            throw new CustomException("数据异常");
        }
        cartItem.setDelFlag("1");
        cartItem.setUpdateBy(userId);
        cartItem.setUpdateTime(new Date());
        cartItem.setLastUpdateTime(new Date());
        cartItemMapper.updateByPrimaryKey(cartItem);
    }

    @Override
    public PreOrderResponseVo preOrder(GoodsCartPreOrderParam orderParam) {
        User user = userService.get(orderParam.getUserId());
        List<Long> ids = orderParam.getCartItemIds();
        GoodsCart cart = this.cartMapper.selectByPrimaryKey(orderParam.getGoodsCartId());
        List<GoodsCartItem> cartItemList = cartItemMapper.selectByGoodsCartId(cart.getId());
        Map<Long, GoodsCartItem> itemMap = cartItemList.stream().collect(Collectors.toMap(GoodsCartItem::getId, Function.identity()));
        List<GoodsCartItem> list = new ArrayList<>(ids.size());
        for (Long id : ids) {
            GoodsCartItem cartItem = itemMap.get(id);
            Goods goods = goodsService.get(cartItem.getGoodsId());
            Integer stock = goods.getStock();
            Integer quantity = cartItem.getQuantity();
            if (stock < quantity) {
                throw new CustomException(goods.getName() + "库存不足");
            }
            list.add(cartItem);
        }
        Order order = orderService.createGoodsOrder(list, orderParam.getUserId(), user.getRegimentId(), orderParam.getAppid(), orderParam.getRecMan(), orderParam.getDeptId());
        list.stream().forEach(cartItem -> {
            cartItem.setStatus("1");
            cartItem.setUpdateBy(orderParam.getUserId());
            cartItem.setUpdateTime(new Date());
            cartItem.setLastUpdateTime(new Date());
            cartItemMapper.updateByPrimaryKey(cartItem);
        });
        List<GoodsCartItem> cartItems = cartItemMapper.selectByGoodsCartIdAndStatus(cart.getId(), "0");
        BigDecimal sum = BigDecimal.ZERO;
        Integer num = 0;
        for (GoodsCartItem cartItem : cartItems) {
            sum = sum.add(cartItem.getTotalPrice());
            num = num + cartItem.getQuantity();
        }
        cart.setTotalPrice(sum);
        cart.setNum(num);
        cart.setUpdateTime(new Date());
        cart.setLastUpdateTime(new Date());
        cartMapper.updateByPrimaryKey(cart);
        return orderService.pay(order.getId(), order.getUserId());
    }

    @Override
    public PreOrderResponseVo newOrder(GoodsCartPreOrderParam orderParam) {
        Order order = orderService.createNewGoodsOrder(orderParam.getGoodsItems(), orderParam.getUserId(), orderParam.getAppid(), orderParam.getRecMan(), orderParam.getDeptId());
        return orderService.pay(order.getId(), order.getUserId());
    }
}
